package media
{
	import events.MyEvent;
	
	import flash.events.*;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.media.SoundMixer;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	public class SoundFacade extends EventDispatcher
	{
		public var s:Sound; 
		public var sc:SoundChannel; 
		public var url:String; 
		public var bufferTime:int = 1000; 
		
		public var isLoaded:Boolean = false; 
		public var isReadyToPlay:Boolean = false; 
		public var isPlaying:Boolean = false; 
		public var isStreaming:Boolean = true; 
		public var autoLoad:Boolean = true; 
		public var autoPlay:Boolean = true; 
		
		public var pausePosition:int = 0; 
		
		public static const PLAY_PROGRESS:String = "playProgress"; 
		public var progressInterval:int = 10; 
		public var playTimer:Timer; 
		public function SoundFacade(soundUrl:String, autoLoad:Boolean = true,autoPlay:Boolean = true, streaming:Boolean = true, bufferTime:int = -1):void 
		{
			this.url = soundUrl; 
			
			// Sets Boolean values that determine the behavior of this object 
			this.autoLoad = autoLoad; 
			this.autoPlay = autoPlay; 
			this.isStreaming = streaming; 
			
			// Defaults to the global bufferTime value 
			if (bufferTime < 0) 
			{ 
				bufferTime = SoundMixer.bufferTime; 
			} 
			
			// Keeps buffer time reasonable, between 0 and 30 seconds 
			this.bufferTime = Math.min(Math.max(0, bufferTime), 30000); 
			
			if (autoLoad) 
			{ 
				load(); 
			} 
		}
		
		public function load():void 
		{ 
			if (this.isPlaying) 
			{ 
				this.stop(); 
				this.s.close(); 
			} 
			this.isLoaded = false; 
			
			this.s = new Sound(); 
			
			this.s.addEventListener(ProgressEvent.PROGRESS, onLoadProgress); 
			this.s.addEventListener(Event.OPEN, onLoadOpen); 
			this.s.addEventListener(Event.COMPLETE, onLoadComplete); 
			this.s.addEventListener(SampleDataEvent.SAMPLE_DATA,sineWaveGenerator);
			//			this.s.addEventListener(Event.ID3, onID3); 
			//			this.s.addEventListener(IOErrorEvent.IO_ERROR, onIOError); 
			//			this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onIOError); 
			
			var req:URLRequest = new URLRequest(this.url); 
			
			var context:SoundLoaderContext = new SoundLoaderContext(this.bufferTime, true); 
			this.s.load(req, context); 
		}
		
		private function sineWaveGenerator(event:SampleDataEvent):void
		{
			trace(event.data);
			this.dispatchEvent(event.clone());
		}
		
		public function onLoadOpen(event:Event):void 
		{ 
			if (this.isStreaming) 
			{ 
				this.isReadyToPlay = true; 
				if (autoPlay) 
				{ 
					this.play(); 
				} 
			} 
			this.dispatchEvent(event.clone()); 
		} 
		
		public function onLoadProgress(event:ProgressEvent):void 
		{  
			this.dispatchEvent(event.clone()); 
		} 
		
		public function onLoadComplete(event:Event):void 
		{ 
			this.isReadyToPlay = true; 
			this.isLoaded = true; 
			this.dispatchEvent(event.clone()); 
			
			if (autoPlay && !isPlaying) 
			{ 
				play(); 
			} 
		}
		
		public function play(pos:int = 0):void 
		{ 
			if (!this.isPlaying) 
			{ 
				if (this.isReadyToPlay) 
				{ 
					this.sc = this.s.play(pos); 
					this.sc.addEventListener(Event.SOUND_COMPLETE, onPlayComplete)
					this.isPlaying = true; 
					
					if(!this.playTimer)
					{
						this.playTimer = new Timer(this.progressInterval); 
						this.playTimer.addEventListener(TimerEvent.TIMER, onPlayTimer); 
					}
					
					this.playTimer.start(); 
					
				} 
			} 
		}
		
		private function onPlayComplete(e:Event):void
		{
			this.isPlaying=false;
			//this.dispatchEvent(e.clone()); 
			this.dispatchEvent(new MyEvent("playComlete"));
		}
		
		public function onPlayTimer(event:TimerEvent):void  
		{ 
			//trace(this.s.length);
			//trace(this.sc.position);
			//var estimatedLength:int =Math.ceil(this.s.length / (this.s.bytesLoaded / this.s.bytesTotal)); 
			//var progEvent:ProgressEvent =  new ProgressEvent(PLAY_PROGRESS, false, false, this.sc.position, estimatedLength); 
			this.dispatchEvent(new MyEvent("playtime",this.sc.position));
			//this.dispatchEvent(progEvent); 
		}
		
		public function stop(pos:int = 0):void 
		{ 
			if (this.isPlaying) 
			{ 
				this.pausePosition = pos; 
				this.sc.stop(); 
				this.playTimer.stop(); 
				this.isPlaying = false; 
			}     
		}
		
		public function pause():void 
		{ 
			stop(this.sc.position); 
		} 
		
		public function resume():void 
		{ 
			play(this.pausePosition); 
		}
	}
}